/**
 * Copyright 厦门中软海晟信息技术有限公司 版权所有 违者必究 2019
 */
package com.opencvjava.practise;

import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import static com.opencvjava.support.util.CvUtils.imshow;
import static com.opencvjava.support.util.CvUtils.mat;

/**
 * @author : sunzb(sunzb@hsit.com.cn)
 * @date: 2019/1/30
 */
@Service
public class MarkDifference {

    private final Logger logger = LoggerFactory.getLogger(MarkDifference.class);
    public void test1() {
        Mat src = mat("MarkDifference", "1.jpg");
        Mat compare = mat("MarkDifference", "3.jpg");
        imshow("源图", src);
        imshow("比较的图", compare);
        Mat dst = src.clone();
        Mat graySrc = new Mat();
        Mat grayCompare = new Mat();
        Imgproc.cvtColor(src, graySrc, Imgproc.COLOR_BGR2GRAY);
        Imgproc.cvtColor(compare, grayCompare, Imgproc.COLOR_BGR2GRAY);
        byte[] dataSrc = new byte[(int) src.total()];
        byte[] dataCompare = new byte[(int) src.total()];
        graySrc.get(0, 0, dataSrc);
        grayCompare.get(0, 0, dataCompare);
        int rows = src.rows();
        int cols = src.cols();
        int index, colorSrc, colorCompare, sumSrc, sumCompare, meanSrc, meanCompare;
        for (int row = 0; row < rows - 7; row += 7) {
            for (int col = 0; col < cols - 7; col += 7) {
                sumCompare = sumSrc = 0;
                for (int nowRow = row; nowRow < row + 7; nowRow++) {
                    for (int nowCol = col; nowCol < col + 7; nowCol++) {
                        index = nowRow * cols + nowCol;
                        colorSrc = dataSrc[index] & 0xff;
                        colorCompare = dataCompare[index] & 0xff;
                        sumSrc += colorSrc;
                        sumCompare += colorCompare;
                    }
                }
                meanSrc = sumSrc / 49;
                meanCompare = sumCompare / 49;
                sumSrc = sumCompare = 0;
                for (int nowRow = row; nowRow < row + 7; nowRow++) {
                    for (int nowCol = col; nowCol < col + 7; nowCol++) {
                        index = nowRow * cols + nowCol;
                        colorSrc = dataSrc[index] & 0xff;
                        colorCompare = dataCompare[index] & 0xff;
                        sumSrc += Math.pow(colorSrc - meanSrc, 2);
                        sumCompare += Math.pow(colorCompare - meanCompare, 2);
                    }
                }
                // 主要调节这个阈值
                if (Math.abs(sumCompare - sumSrc) > 3500) {
                    Imgproc.rectangle(dst, new Rect(new Point(col, row), new Size(7, 7)), new Scalar(0, 0, 255), 2, 8, 0);
                }
            }
        }
        imshow("结果", dst);
    }

    public void test() {
        Mat src = mat("MarkDifference", "1.jpg");
        Mat compare = mat("MarkDifference", "3.jpg");
        imshow("源图", src);
        imshow("比较的图", compare);
        Mat dst = src.clone();
        byte[] dataSrc = new byte[(int) src.total() * 3];
        byte[] dataCompare = new byte[(int) src.total() * 3];
        src.get(0, 0, dataSrc);
        compare.get(0, 0, dataCompare);
        int rows = src.rows();
        int cols = src.cols();
        int index, b, g, r, sumSrcb, sumSrcg, sumSrcr,
                sumCompareb, sumCompareg, sumComparer,
                meanSrcb, meanSrcg, meanSrcr,
                meanCompareb, meanCompareg, meanComparer;
        for (int row = 0; row < rows - 5; row += 5) {
            for (int col = 0; col < cols - 5; col += 5) {
                sumSrcb = sumSrcg = sumSrcr = sumCompareb = sumCompareg = sumComparer = 0;
                for (int nowRow = row; nowRow < row + 5; nowRow++) {
                    for (int nowCol = col; nowCol < col + 5; nowCol++) {
                        index = nowRow * cols + nowCol;
                        b = dataSrc[index] & 0xff;g = dataSrc[index + 1] & 0xff;r = dataSrc[index + 2] & 0xff;
                        sumSrcb += b;sumSrcg += g;sumSrcr += r;
                        b = dataCompare[index] & 0xff;g = dataCompare[index + 1] & 0xff;r = dataCompare[index + 2] & 0xff;
                        sumCompareb += b;sumCompareg += g;sumComparer += r;
                    }
                }
                meanSrcb = sumSrcb / 25;meanSrcg = sumSrcg / 25;meanSrcr = sumSrcr / 25;
                meanCompareb = sumCompareb / 25;meanCompareg = sumCompareg / 25;meanComparer = sumComparer / 25;
                if (Math.abs(meanCompareb - meanSrcb) > 5 ||
                        Math.abs(meanCompareg - meanSrcg) > 5 ||
                        Math.abs(meanComparer - meanSrcr) > 5) {
                    Imgproc.rectangle(dst, new Rect(new Point(col, row), new Size(5, 5)), new Scalar(0, 0, 255), 2, 8, 0);
                }
                sumSrcb = sumSrcg = sumSrcr = sumCompareb = sumCompareg = sumComparer = 0;
                for (int nowRow = row; nowRow < row + 5; nowRow++) {
                    for (int nowCol = col; nowCol < col + 5; nowCol++) {
                        index = nowRow * cols + nowCol;
                        b = dataSrc[index] & 0xff;g = dataSrc[index + 1] & 0xff;r = dataSrc[index + 2] & 0xff;
                        sumSrcb += Math.pow(b - meanSrcb, 2);sumSrcg += Math.pow(g - meanSrcg, 2);sumSrcr += Math.pow(r - meanSrcr, 2);
                        b = dataCompare[index] & 0xff;g = dataCompare[index + 1] & 0xff;r = dataCompare[index + 2] & 0xff;
                        sumCompareb += Math.pow(b - meanCompareb, 2);sumCompareg += Math.pow(g - meanCompareg, 2);sumComparer += Math.pow(r - meanComparer, 2);
                    }
                }
                /*if (Math.abs(sumCompareb - sumSrcb) +
                        Math.abs(sumCompareg - sumSrcg) +
                        Math.abs(sumComparer - sumSrcr) > 10000) {
                    Imgproc.rectangle(dst, new Rect(new Point(col, row), new Size(5, 5)), new Scalar(0, 0, 255), 2, 8, 0);
                }*/
            }
        }
        imshow("结果", dst);
    }
}
